package com.daxt.utils.file;

import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.util.*;
import java.util.List;
import java.util.regex.Pattern;

import javax.imageio.ImageIO;

import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.daxt.base.common.util.RedisUtil;
import com.daxt.model.dic.VersionsMarkType;
import com.daxt.utils.BaseUtil;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.parser.PdfTextExtractor;
import com.lowagie.text.*;
import org.apache.pdfbox.cos.COSDocument;
import org.apache.pdfbox.io.RandomAccessBufferedFileInputStream;
import org.apache.pdfbox.io.RandomAccessRead;
import org.apache.pdfbox.pdfparser.PDFParser;
import org.apache.pdfbox.text.PDFTextStripper;
import org.springframework.stereotype.Service;

import com.lowagie.text.pdf.PdfWriter;


import java.io.File;

import com.spire.pdf.*;

@Service
public class PdfUtils {


    public static void toPdf(File[] files, String imageFolderPath, String pdfPath, String pdfName) throws Exception {
        FileOutputStream fos = null;
        Document doc = new Document(null, 0, 0, 0, 0);
        try {

            String imagePath = null;

            if (files.length == 0)
                return;
            File pdfDir = new File(pdfPath);
            if (!pdfDir.exists())
                pdfDir.mkdirs();
            fos = new FileOutputStream(pdfPath + pdfName + ".pdf");
            PdfWriter.getInstance(doc, fos);
            BufferedImage img = null;
            Image image = null;
            Map<Float, Object> treeMapImg = new TreeMap<Float, Object>();
            List<String> listImg = new ArrayList<String>();
            for (File file1 : files) {

                int indexOf = file1.getName().indexOf(".");
                if (indexOf > 0) {

                    if (FileBaseUtil.isImg(FileBaseUtil.getFileExtName(file1))) {
//					if (file1.getName().endsWith(".png") || file1.getName().endsWith(".jpg")
//							|| file1.getName().endsWith(".PNG") || file1.getName().endsWith(".JPG")
//							|| file1.getName().endsWith(".gif") || file1.getName().endsWith(".jpeg")
//							|| file1.getName().endsWith(".tif")) {


                        if (RedisUtil.isAppoint(VersionsMarkType.VERSIONS_2)) {
                            String fileName = BaseUtil.getFileName(file1.getName());
                            String fileNameNum = fileName.substring(fileName.indexOf("_") + 1);
                            fileNameNum = fileNameNum.replaceAll("-", ".");
//							//附件追加
//							String fileNameNumAddTo = fileNameNum.substring(fileName.indexOf("-")+1);
//							if(!StringUtils.isEmpty(fileNameNumAddTo)){
//
//							}
                            //add 增加图片排序，如果可以转成数字，那按照数字升序 lig 2021-06-08
                            if (BaseUtil.isStr2Num(fileNameNum)) {
                                treeMapImg.put(Float.parseFloat(fileNameNum), imageFolderPath + file1.getName());
//								treeMapImg.put(Float.parseFloat(fileNameNum),imageFolderPath + file1.getName());
                            } else {
                                listImg.add(imageFolderPath + file1.getName());
                            }
                        } else {
                            listImg.add(imageFolderPath + file1.getName());
                        }
                    }
                }
            }
            //增加写入图片 lig 2021-06-08
            List<String> l = new ArrayList();
            for (Map.Entry<Float, Object> entry : treeMapImg.entrySet()) {
                l.add(entry.getValue().toString());
            }

            l.addAll(listImg);
            for (String imgPath : l) {
                img = ImageIO.read(new File(imgPath));
                if (img != null) {
                    doc.setPageSize(new Rectangle(img.getWidth(), img.getHeight()));

                    String imgBase64 = TiffToImgUtil.imageToBase64(imgPath);
                    if(TiffToImgUtil.checkImageBase64Format(imgBase64)){
                        TiffToImgUtil.tiffToJpg(imgPath,imgPath);
                    }
                    image = Image.getInstance(imgPath);
                    doc.open();
                    doc.add(image);
                }
            }


        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (doc.isOpen())
                doc.close();
            if (fos != null) {
                fos.flush();
                fos.close();
            }
        }

    }



    /**
     * 读取pdf参考文献内容
     *
     * @param
     * @return
     */
    public static String readPdf(String filePath) {
        Pattern pattern = Pattern.compile("\\d+");
        int stateParaOverFlag = 800;
        int thankParaOverFlag = 800;

        StringBuilder buffer = new StringBuilder();
        FileInputStream fis = null;
        PdfReader pdfReader = null;
        COSDocument cosDocument = null;
        String[] paragraphs = null;
        PDFParser p;
        boolean addBool = true;
        boolean judgeState = false;
        boolean judgeThank = false;
        StringBuilder tempSb = new StringBuilder();
        try {
            fis = new FileInputStream(filePath);
            RandomAccessRead randomAccessRead = new RandomAccessBufferedFileInputStream(fis);
            p = new PDFParser(randomAccessRead);
            p.parse();
            cosDocument = p.getDocument();
            // 加密文档判断
            if (cosDocument.isEncrypted()) {
                StringBuilder tempContent = new StringBuilder();
                pdfReader = new PdfReader(filePath);
                int i = pdfReader.getNumberOfPages();
                for (int j = 1; j <= i; j++) {
                    tempContent.append(PdfTextExtractor.getTextFromPage(pdfReader, j));
                }
                paragraphs = tempContent.toString().split("\n");
            } else {
                PDFTextStripper ts = new PDFTextStripper();
                paragraphs = ts.getText(p.getPDDocument()).split("\n");
            }
            boolean mark = false;
            List<Integer> errornum = new ArrayList<Integer>();
            int flag = 0;
            int endRange = paragraphs.length * 70 / 100;
            int rangeFlag = 0;
            for (String lineContent : paragraphs) {
                if (judgeState) {
                    tempSb.append(lineContent);
                    if (tempSb.length() >= stateParaOverFlag) {
                        judgeState = false;
                        addBool = true;
                        tempSb.delete(0, tempSb.length() - 1);
                    }
                }
                if (judgeThank) {
                    tempSb.append(lineContent);
                    if (tempSb.length() >= thankParaOverFlag) {
                        judgeThank = false;
                        addBool = true;
                        tempSb.delete(0, tempSb.length() - 1);
                    }
                }
                if (addBool) {
                    buffer.append(lineContent);
                }
                if (mark && rangeFlag >= endRange) {
                    if (lineContent.length() < 5) {
                        errornum.add(++flag);
                        rangeFlag++;
                        continue;
                    }
                    if (pattern.matcher(lineContent.substring(0, 5)).find()) {
                        if (flag != 0) {
                            flag = 0;
                            errornum.clear();
                        }
                    } else {
                        errornum.add(++flag);
                    }
                    if (errornum.size() > 2) {
                        mark = false;
                    }
                }
                rangeFlag++;
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (fis != null) {
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    fis = null;
                }
            }
            if (pdfReader != null) {
                pdfReader.close();
            }
            if (cosDocument != null) {
                try {
                    cosDocument.close();
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    cosDocument = null;
                }
            }
        }
        return buffer.toString();
    }

    public static boolean isBlank(CharSequence cs) {
        int strLen;
        if (cs == null || (strLen = cs.length()) == 0) {
            return true;
        }
        for (int i = 0; i < strLen; i++) {
            if (Character.isWhitespace(cs.charAt(i)) == false) {
                return false;
            }
        }
        return true;
    }




    /**
     * @description: 获取pdf内容  文本及图片
     * @param pdfUrl    pdf全路径
     * @param tempPath 图片临时存放路径 结尾"/"
     *
     * @author: lig
     * @date: 2022/2/15
     */
    public static Map<String,Object> gainPdfContent(String pdfUrl,String tempPath){
        Map<String,Object> m = new HashMap();
        PdfDocument pdf = new PdfDocument(pdfUrl);

        try{

            //实例化StringBuilder类
            StringBuilder sb = new StringBuilder();
            int index = 0;
            //遍历PDF文档中每页
            PdfPageBase page;
            System.err.println("pdf页数："+pdf.getPages().getCount());
            for (int i= 0; i<pdf.getPages().getCount();i++) {
                page = pdf.getPages().get(i);
                //调用extractText()方法提取文本
                sb.append(page.extractText(true));


//                FileWriter writer;
    //            try {
    //                //将StringBuilder对象中的文本写入到txt
    //                writer = new FileWriter("ExtractText.txt");
    //                writer.write(sb.toString());
    //                writer.flush();
    //            } catch (IOException e) {
    //                e.printStackTrace();
    //            }

                Map imgs = new HashMap();
                String get32uuid = IdWorker.get32UUID();
                String temp = tempPath + get32uuid + "/";
                File f = new File(temp);
                f.mkdir();
                if(null !=  page.extractImages()){
                    //调用extractImages方法获取图片
                    for (BufferedImage image : page.extractImages()) {
                        //指定输出图片名，指定图片格式
                        File output = new File(temp + String.format("Image_%d.png", index++));
                        ImageIO.write(image, "PNG", output);


                        imgs.put(output.getName(),output.getAbsolutePath());
                    }
                    m.put("imgs",imgs);
                }
            }
            String text = sb.toString().trim();
            text = text.replaceAll("\r","");
            text = text.replaceAll("\n","");
            text = text.replaceAll(" ","");
            m.put("text",text);
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            pdf.close();
        }


        return m;
    }

    /**
     * @description: 图片转换为pdf
     *  imgPaths:存放图片路径的集合，pdfPath：pdf的路径
     */
    public static void imgToPdf(List<String> imgPaths,String pdfPath) {
        try {
            //创建个存放图片地址的集合
            List<String> imageUrlList = new ArrayList();
            //添加图片地址到集合
            for(String imgPath:imgPaths){
                imageUrlList.add(imgPath);
            }
            File file = pdf(imageUrlList, pdfPath);//生成pdf
            file.createNewFile();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void oneImgToPdf(String imageUrl, String pdfPath) {
        List<String> imgPaths=new ArrayList<>();
        imgPaths.add(imageUrl);
        imgToPdf(imgPaths,pdfPath);
    }

    public static File pdf(List<String> imageUrllist, String pdfUrl) {
        //new一个pdf文档
        Document doc=null;
        if(imageUrllist.size()==1){
            String imgPath = imageUrllist.get(0);
            File srcImgFile = new File(imgPath);
            try {
                java.awt.Image srcImg = ImageIO.read(srcImgFile);
                float imgWidth = srcImg.getWidth(null);
                float imgHeight = srcImg.getHeight(null);


                Rectangle rectangle = new Rectangle(imgWidth  , imgHeight);
                doc= new Document(rectangle,0,0,0,0);

            }catch (IOException io){
                io.printStackTrace();
            }
        }else{
             doc= new Document(PageSize.A4, 20, 20, 20, 20);
        }

        try {
            //pdf写入
            PdfWriter.getInstance(doc, new FileOutputStream(pdfUrl));
            //打开文档
            doc.open();
            //遍历集合，将图片放在pdf文件
            for (int i = 0; i < imageUrllist.size(); i++) {
                //在pdf创建一页   主：此处为每一张图片是pdf文件的一页
                doc.newPage();
                //通过文件路径获取image
                Image png1 = Image.getInstance(imageUrllist.get(i));
                float heigth = png1.getHeight();
                float width = png1.getWidth();
                //int percent = getPercent2(heigth, width);
                //png1.setAlignment(Image.MIDDLE);
                // 表示是原来图像的比例;
                //png1.scalePercent(percent+3);
                doc.add(png1);
            }
            doc.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (DocumentException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        //输出流
        File mOutputPdfFile = new File(pdfUrl);
        if (!mOutputPdfFile.exists()) {
            mOutputPdfFile.deleteOnExit();
            return null;
        }
        //反回文件输出流
        return mOutputPdfFile;
    }

    public static int getPercent(float h, float w) {
        int p = 0;
        float p2 = 0.0f;
        if (h > w) {
            p2 = 297 / h * 100;
        } else {
            p2 = 210 / w * 100;
        }
        p = Math.round(p2);
        return p;
    }

    public static int getPercent2(float h, float w) {
        int p = 0;
        float p2 = 0.0f;
        p2 = 530 / w * 100;
        p = Math.round(p2);
        return p;
    }

    public static int getPdfPageCount(String pdfUrl){
        int pageCount=1;
        Map<String,Object> m = new HashMap();
        PdfDocument pdf = new PdfDocument(pdfUrl);
        try{

            //实例化StringBuilder类
            StringBuilder sb = new StringBuilder();
            int index = 0;
            //遍历PDF文档中每页
            PdfPageBase page;
            pageCount = pdf.getPages().getCount();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            pdf.close();
        }
        return pageCount;
    }

    //public static void main(String[]args) throws Exception {

        //Map m = gainPdfContent("F:\\zjq\\pdf测试文件\\0001.pdf","D:/home/jar/temp/");
        //System.out.println(m.get("text"));
        //System.out.println(m.get("imgs"));

        //http://192.168.0.200:9000/static/12/37/2035/doc/8941/001.pdf

        //Map m = gainPdfContent("C:\\Users\\Administrator\\Desktop\\a001.pdf","D:\\a\\");
        //System.err.println("mapSize:"+m.size());
//        Map m = gainPdfContent("C:\\Users\\Administrator\\Desktop\\aaaaaaa.pdf","D:\\home\\jar\\temp\\");
//        System.err.println("mapSize:"+m.size());
    //}

//    public static void main(String[] args) {
//        // System.err.println(new UploadUtils()
//        // .readPdf("/opt/fileCache/2014/125/13/shuangping_D7037870CF4FC5C421A3E5359DCF8BBE.pdf"));
//        System.err.println(readPdf("C:\\Users\\Administrator\\Desktop\\222\\002.pdf"));
//
//    }


//    public static void main(String[] args) {
//        Map<Float, Object> treeMapImg = new TreeMap<Float, Object>();
//        treeMapImg.put(1f, "1111");
//        treeMapImg.put(1.1f, "1111");
//        treeMapImg.put(2f, "1111");
//        treeMapImg.put(3f, "1111");
//
//
////		// 遍历方法四 treemap keySet()遍历
////		for (Object o : treeMapImg.keySet()) {
////			System.out.println("key=" + o + " value=" + tempMap.get(o));
////		}
//
//        for (Map.Entry<Float, Object> entry : treeMapImg.entrySet()) {
//            String key = entry.getKey().toString();
//            String value = entry.getValue().toString();
//            System.out.println("key=" + key + " value=" + value);
//        }
//
//
//    }
}
